/**
 *  Copyright (C) 2008-2013  Telosys project org. ( http://www.telosys.org/ )
 *
 *  Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *          http://www.gnu.org/licenses/lgpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.telosys.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Utility class for FILE operations ( set of static methods )
 * 
 * @author Laurent GUERIN
 * 
 */
public class FileUtil
{
    private static final int BUFFER_SIZE = 1024 ; // 1 kb            

    //----------------------------------------------------------------------------
    /**
     * Private constructor
     */
    private FileUtil()
    {
    }
    
    //----------------------------------------------------------------------------
    /**
     * Save a memory content in a file
     * @param sFileName 
     * @param content
     * @throws Exception
     */
    public static void save(String sFileName, byte[] content) throws Exception
    {
        FileOutputStream fos = null ;
        try
        {
            fos = new FileOutputStream(sFileName);
        } catch (FileNotFoundException ex)
        {
            throw new Exception("save : cannot open file.", ex);
        }
        if ( fos != null )
        {
            try
            {
                fos.write(content, 0, content.length );
                fos.close();
            } catch (IOException ioex)
            {
                throw new Exception("save : write error.", ioex);
            }
        }
    }
    
    //----------------------------------------------------------------------------
    /**
     * Load a file content in memory
     * @param sFileName
     * @return file content or null if the file doesn't exist
     * @throws Exception
     */
    public static byte[] load(String sFileName) throws Exception
    {
        FileInputStream fis = null ;
        try
        {
            fis = new FileInputStream(sFileName);
        } catch (FileNotFoundException ex)
        {
            throw new Exception("load : cannot open file.", ex);
        }
        //--- Process the file
        ByteArrayOutputStream os = new ByteArrayOutputStream(BUFFER_SIZE);
        byte [] buffer = new byte [BUFFER_SIZE] ; 
        int i = 0;
        try
        {
            while ( ( i = fis.read(buffer) ) > 0 )
            {
                os.write(buffer, 0, i);                
            }
            fis.close();
            //os.close(); // no effect on a ByteArrayOutputStream
        } catch (IOException ioex)
        {
            throw new Exception("load : read error.", ioex);
        }
        return os.toByteArray();
    }
    
    //----------------------------------------------------------------------------
    /**
     * Copy a file into another one
     * @param sInputFileName
     * @param sOutputFileName
     * @throws Exception
     */
    public static void copy(String sInputFileName, String sOutputFileName) throws Exception
    {
        //--- Open input file
		FileInputStream fis = null;
        try
        {
            fis = new FileInputStream(sInputFileName);
        } catch (FileNotFoundException ex)
        {
            throw new Exception("copy : cannot open input file.", ex);
        }
        
        //--- Open output file
		FileOutputStream fos = null;
        try
        {
            fos = new FileOutputStream(sOutputFileName);
        } catch (FileNotFoundException ex)
        {
            throw new Exception("copy : cannot open output file.", ex);
        }
        
        //--- Copy and close
        if ( fis != null && fos != null )
        {
			byte buffer[] = new byte[BUFFER_SIZE];
			int len = 0;
			
			try
            {
                while ((len = fis.read(buffer)) > 0)
                {
                    fos.write(buffer, 0, len);
                }
                fis.close();
                fos.close();
            } catch (IOException ioex)
            {
                throw new Exception("copy : IO error.", ioex);
            }
		}
    }
    
    //----------------------------------------------------------------------------
    /**
     * Delete a file (and only a file)
     * @param sFileName the full name of the file to delete
     * @return true if and only if the file or directory is successfully deleted; false otherwise
     * @throws Exception if the given filename is not a 'normal file' ( directory or other )
     */
    public static boolean delete(String sFileName) throws Exception
    {
        File file = new File(sFileName);
        if ( file.exists() )
        {
	        if ( file.isFile() )
	        {
	            return file.delete();
	        }
	        else
	        {
	            throw new Exception("delete : " + sFileName + " is not a file.");
	        }
        }
        else
        {
            return false ;
        }
    }
    //-----------------------------------------------------------------------------
    /**
     * Checks the existence of a file
     * 
     * @param sFileName
     * @return true if the file exists and is realy a file (not a directory)
     * @since v 1.1.0
     */
    public static boolean exists(String sFileName)
    {
        File file = new File(sFileName);
        return file.isFile() ;
    }
    
    /**
     * Builds a path like "LeftPart" + SEPARATOR + "RightPart" without redundant separators
     * @param sLeftPart : left part ( with or without ending separator )
     * @param sRightPart : right part ( with or without starting separator ) 
     * @param sSeparatorArg : the separator to use ( e.g. "/", ".", ... )
     * @return the resulting path
     */
    public static String buildPath(String sLeftPart, String sRightPart, String sSeparatorArg )
    {
        String sRoot = "";
        String sFile = "";
        String sSeparator = "/";
        if (sRightPart != null)
        {
            sFile = sRightPart.trim();
        }
        if (sLeftPart != null)
        {
            sRoot = sLeftPart.trim();
        }
        if (sSeparatorArg != null)
        {
            sSeparator = sSeparatorArg.trim();
        }

        if (sRoot.endsWith(sSeparator))
        {
            sRoot = sRoot.substring(0, sRoot.length() - 1);
        }
        if (sFile.startsWith(sSeparator))
        {
            sFile = sFile.substring(1);
        }
        return sRoot + sSeparator + sFile;
    }
    
}
